// Copyright (c) Microsoft Corporation. All rights reserved.

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Text.RegularExpressions;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Migration.Toolkit;
using Microsoft.TeamFoundation.Migration.Toolkit.VC;

namespace Microsoft.Vsts.Rangers.Migration.TfsToTfs
{
    class TfsToTfsMigrationEngine : SourceToTfsMigrationEngine
    {
        private Session m_Session;

        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="session">Session this migration engine belongs to</param>
        /// <param name="manager">Changegroup manager of this migration engine</param>
        public TfsToTfsMigrationEngine(Session session, ChangeGroupingMananger manager)
            : base(session, manager)
        {
            m_Session = session;
        }

        //protected override void Add(IMigrationAction action, BatchingContext context)
        //{
        //    TfsMigrationItem sourceItem = (TfsMigrationItem)action.SourceItem;
        //    if (!sourceItem.IsDirectory)
        //    {
        //        base.Add(action, context);
        //    }
        //}

        //protected override void Branch(IMigrationAction action, BatchingContext context)
        //{
        //    TfsMigrationItem sourceItem;

        //    if (action.TargetSourceItem == null)
        //    {
        //        sourceItem = (TfsMigrationItem)action.SourceItem;
        //    }
        //    else
        //    {
        //        sourceItem = (TfsMigrationItem)action.TargetSourceItem;
        //    }

        //    TfsMigrationItem targetItem = (TfsMigrationItem)action.TargetTargetItem;

        //    context.PendBranch(
        //        sourceItem.ServerPath,
        //        targetItem.ServerPath);
        //}



        /// <summary>
        /// Handle single item error events. 
        /// 1. For add existing item, fire warning events and continue 
        /// 2. For all other situations, fire error events and call base.SingleItemError 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected override void SingleItemError(object sender, BatchedItemEventArgs e)
        {
            if ((e.Target != null) && (e.Exception is MigrationException))
            {
                switch (e.Target.Action)
                {
                    case ChangeAction.Add:
                        string pattern = ResourceStrings.ItemExistsException;
                        Regex regex = new Regex(pattern);
                        if (regex.IsMatch(e.Exception.Message))
                        {
                            // Trigger the session warning event
                            base.SingleItemWarning(sender, e);
                        }
                        return;
                    default:
                        break;
                }
            }

            base.SingleItemError(sender, e);
        }

        protected override void ProcessChangeGroup(ChangeGrouping group)
        {
            // Process the groups only when going to the same direction
            if ((group.Direction == MigrationDirection.TfsToSource && !((Session)Session).isForwardMigration)
                || (group.Direction == MigrationDirection.SourceToTfs && ((Session)Session).isForwardMigration))
            {
                try
                {

                    base.ProcessChangeGroup(group);
                }
                catch (Exception ex)
                {
                    // just fire the event.
                    // don't want to undo the workspace changes here since they may be needed for manually
                    // working around an issue and they wil be cleaned up when ProcessChangeGroup is next called.
                    // additionally we don't want to do anything expensive in a catch block since the
                    // exception may have been for a resource or thread abort (i.e. shutdown) reason.

                    SystemType sourceSystem = (((Session)Session).isForwardMigration) ? SystemType.Other : SystemType.Tfs;
                    Session.OnMigrationError(new VersionControlEventArgs(ex.Message, ex, sourceSystem));
                    throw;
                }
            }
        }

        protected override bool IsOurTfsChanges(int changesetId)
        {
            Changeset c = TfsClient.GetChangeset(changesetId, false, false);
            return TfsUtil.IsOurTfsChange(c, CommentModifier);
        }
    }
}
